#pragma once
#ifndef xTrace_h__
#define xTrace_h__

//#include "../../dxhead/dxegheader.h"
#include "./skyType.h"

namespace Sky
{
//////////////////////////////////////////////////////////////////////////
		//#define xStaticAssert(bool_expr,msg) typedef TInt _check[bool_expr]
		//#define xStaticAssert(bool_expr,msg) typedef int msg[bool_expr? 1 : -1]
		template<int> struct CompileTimeError{public: typedef int is_ok[0];};
		template<> struct CompileTimeError<true> {public: typedef int is_ok;};
#define xStaticAssert(expr, msg) typedef Sky::CompileTimeError<((expr) != 0)>::is_ok msg[expr ? 1:0]

//////////////////////////////////////////////////////////////////////////
		namespace TraceLevel
		{
			typedef enum _xTraceLevel
			{
				S,
				E,
				M,
				W,
				I
			}xTraceLevel;
		}


typedef enum _xTraceType
{
	eType_LogFile		= 0x00000001,
	eType_OutConsol		= 0x00000002,
	eType_DbgConsol		= 0x00000004,
	eType_MsgBox		= 0x00000010,
	eType_AssertBox		= 0x00000020,
	eType_DxAssert		= 0x00000040
}xTraceType;



//////////////////////////////////////////////////////////////////////////

#if defined(_XTRACE)
#define _XTRACE_LOGFILE
#define _XTRACE_OUTCONSOLE
#define _XTRACE_DBGCONSOLE
#define _XTRACE_MSGBOX
#define _XTRACE_ASSERT
#define _XTRACE_PRINTF
#define _XTRACE_INFO
#define _XTRACE_WARINIG
#define _XTRACE_ERROR
#endif

#define __XLEVEL__   "(%d)"
#define __XHR__		 ",hr(0x%x)"
#define __XLINE__	",line:%6d"
#define __XFILE__	//",file: "__FILE__
#define __XFUNC__	//","__FUNCTION__"()"


//////////////////////////////////////////////////////////////////////////
TVoid		xTraceA(xTraceType type,TUint traceLevel,const TAchar* fmt,...);
TResult	xTraceHrA(xTraceType type,TUint traceLevel,TResult hr,const TAchar* fmt,...);

TVoid		xTraceW(xTraceType type,TUint traceLevel,const TWchar* fmt,...);
TResult	xTraceHrW(xTraceType type,TUint traceLevel,TResult hr,const TWchar* fmt,...);

#if defined(_XTRACE)

	#define __xTraceW									xTraceW
	#define __xTraceMsgW(traceType,traceLevel,msg)			traceType,TraceLevel::traceLevel,(TWchar*)L("")##traceLevel##""__XLEVEL__""##msg##""__XLINE__""__XFUNC__""__XFILE__"\r\n",TraceLevel::traceLevel

	#define __xTraceHrW									xTraceHrW
	#define __xTraceMsgHrW(traceType,traceLevel,hr,msg)	traceType,TraceLevel::traceLevel,hr,(TWchar*)L("")##traceLevel##""__XLEVEL__""__XHR__","##msg##""__XLINE__""__XFUNC__""__XFILE__"\r\n",TraceLevel::traceLevel,hr

	#define __xTraceA									xTraceA
	#define __xTraceMsgA(traceType,traceLevel,msg)		traceType,TraceLevel::traceLevel,(TAchar*)""#traceLevel##""__XLEVEL__","##msg##""__XLINE__""__XFUNC__""__XFILE__"\r\n",TraceLevel::traceLevel

	#define __xTraceHrA									xTraceHrA
	#define __xTraceMsgHrA(traceType,traceLevel,hr,msg)	traceType,TraceLevel::traceLevel,hr,(TAchar*)""#traceLevel##""__XLEVEL__""__XHR__","##msg##""__XLINE__""__XFUNC__""__XFILE__"\r\n",TraceLevel::traceLevel,hr

	#if  defined(XUNICODE)
		//#define xTrace(...)								    __xTraceW(__VA_ARGS__)

		#define __xTrace									__xTraceW
		#define __xTraceMsg									__xTraceMsgW 

		#define __xTraceHr									__xTraceHrW
		#define __xTraceMsgHr								__xTraceMsgHrW
	#else//!XUNICODE
		#define xTrace(...)								    __xTraceA(__VA_ARGS__)

		#define __xTrace									__xTraceA
		#define __xTraceMsg									__xTraceMsgA

		#define __xTraceHr									__xTraceHrA
		#define __xTraceMsgHr								__xTraceMsgHrA
	#endif//XUNICODE

	#define xTrace0A(traceType,traceLevel,msg)											__xTraceA(__xTraceMsgA(traceType,traceLevel,msg),(TUint)__LINE__)
	#define xTrace1A(traceType,traceLevel,msg,msgArg1)									__xTraceA(__xTraceMsgA(traceType,traceLevel,msg),(TUint)__LINE__,msgArg1)
	#define xTrace2A(traceType,traceLevel,msg,msgArg1,msgArg2)							__xTraceA(__xTraceMsgA(traceType,traceLevel,msg),(TUint)__LINE__,msgArg1,msgArg2)
	#define xTrace3A(traceType,traceLevel,msg,msgArg1,msgArg2,msgArg3)					__xTraceA(__xTraceMsgA(traceType,traceLevel,msg),(TUint)__LINE__,msgArg1,msgArg2,msgArg3)
	#define xTrace4A(traceType,traceLevel,msg,msgArg1,msgArg2,msgArg3,msgArg4)			__xTraceA(__xTraceMsgA(traceType,traceLevel,msg),(TUint)__LINE__,msgArg1,msgArg2,msgArg3,msgArg4)

	#define xTraceHr0A(traceType,traceLevel, hr,msg)									__xTraceHrA(__xTraceMsgHrA(traceType,traceLevel,hr,msg),(TUint)__LINE__)
	#define xTraceHr1A(traceType,traceLevel, hr,msg,msgArg1)							__xTraceHrA(__xTraceMsgHrA(traceType,traceLevel,hr,msg),(TUint)__LINE__,msgArg1)
	#define xTraceHr2A(traceType,traceLevel, hr,msg,msgArg1,msgArg2)					__xTraceHrA(__xTraceMsgHrA(traceType,traceLevel,hr,msg),(TUint)__LINE__,msgArg1,msgArg2)
	#define xTraceHr3A(traceType,traceLevel, hr,msg,msgArg1,msgArg2,msgArg3)			__xTraceHrA(__xTraceMsgHrA(traceType,traceLevel,hr,msg),(TUint)__LINE__,msgArg1,msgArg2,msgArg3)

	#define xTrace0W(traceType,traceLevel,msg)											__xTraceW(__xTraceMsgW(traceType,traceLevel,msg),(TUint)__LINE__)
	#define xTrace1W(traceType,traceLevel,msg, msgArg1)									__xTraceW(__xTraceMsgW(traceType,traceLevel,msg),(TUint)__LINE__,msgArg1)
	#define xTrace2W(traceType,traceLevel,msg, msgArg1, msgArg2)						__xTraceW(__xTraceMsgW(traceType,traceLevel,msg),(TUint)__LINE__,msgArg1,msgArg2)
	#define xTrace3W(traceType,traceLevel,msg, msgArg1, msgArg2, msgArg3)				__xTraceW(__xTraceMsgW(traceType,traceLevel,msg),(TUint)__LINE__,msgArg1,msgArg2,msgArg3)
	#define xTrace4W(traceType,traceLevel,msg, msgArg1, msgArg2, msgArg3,msgArg4)		__xTraceW(__xTraceMsgW(traceType,traceLevel,msg),(TUint)__LINE__,msgArg1,msgArg2,msgArg3,msgArg4)

	#define xTraceHr0W(traceType,traceLevel, hr,msg)									__xTraceHrW(__xTraceMsgHrW(traceType,traceLevel,hr,msg),(TUint)__LINE__)
	#define xTraceHr1W(traceType,traceLevel, hr,msg, msgArg1)							__xTraceHrW(__xTraceMsgHrW(traceType,traceLevel,hr,msg),(TUint)__LINE__,msgArg1)
	#define xTraceHr2W(traceType,traceLevel, hr,msg, msgArg1, msgArg2)					__xTraceHrW(__xTraceMsgHrW(traceType,traceLevel,hr,msg),(TUint)__LINE__,msgArg1,msgArg2)
	#define xTraceHr3W(traceType,traceLevel, hr,msg, msgArg1, msgArg2, msgArg3)			__xTraceHrW(__xTraceMsgHrW(traceType,traceLevel,hr,msg),(TUint)__LINE__,msgArg1,msgArg2,msgArg3)

#else //!_XTRACE
	#define xTrace(...)																	do{}while(0)
	#define xTrace0A(traceType, traceLevel,msg)											do{}while(0)
	#define xTrace1A(traceType, traceLevel,msg,msgArg)									do{}while(0)
	#define xTrace2A(traceType, traceLevel,msg,msgArg1,msgArg2)							do{}while(0)
	#define xTrace3A(traceType, traceLevel,msg,msgArg1,msgArg2,msgArg3)					do{}while(0)
	#define xTrace4A(traceType, traceLevel,msg,msgArg1,msgArg2,msgArg3,msgArg4)			do{}while(0)

	#define xTraceHr0A(traceType, traceLevel, hr,msg)									(hr)
	#define xTraceHr1A(traceType, traceLevel, hr,msg,msgArg)							(hr)
	#define xTraceHr2A(traceType, traceLevel, hr,msg,msgArg1,msgArg2)					(hr)

	#define xTrace0W(traceType, traceLevel,msg)											do{}while(0)
	#define xTrace1W(traceType, traceLevel,msg,msgArg)									do{}while(0)
	#define xTrace2W(traceType, traceLevel,msg,msgArg1,msgArg2)							do{}while(0)
	#define xTrace3W(traceType, traceLevel,msg,msgArg1,msgArg2,msgArg3)					do{}while(0)
	#define xTrace4W(traceType, traceLevel,msg,msgArg1,msgArg2,msgArg3,msgArg4)			do{}while(0)

	#define xTraceHr0W(traceType, traceLevel, hr,msg)									(hr)
	#define xTraceHr1W(traceType, traceLevel, hr,msg,msgArg)							(hr)
	#define xTraceHr2W(traceType, traceLevel, hr,msg,msgArg1,msgArg2)					(hr)

#endif //_XTRACE

#if  defined(XUNICODE)
	#define xTrace0					xTrace0W
	#define xTrace1					xTrace1W
	#define xTrace2					xTrace2W
	#define xTrace3					xTrace3W
	#define xTrace4					xTrace4W

	#define xTraceHr0				xTraceHr0W
	#define xTraceHr1				xTraceHr1W
	#define xTraceHr2				xTraceHr2W
	#define xTraceHr3				xTraceHr3W
#else
	#define xTrace0					xTrace0A
	#define xTrace1					xTrace1A
	#define xTrace2					xTrace2A
	#define xTrace3					xTrace3A
	#define xTrace4					xTrace4A

	#define xTraceHr0				xTraceHr0A
	#define xTraceHr1				xTraceHr1A
	#define xTraceHr2				xTraceHr2A
	#define xTraceHr3				xTraceHr3A
#endif

//////////////////////////////////////////////////////////////////////////
#if defined(_XTRACE_LOGFILE)
	TVoid xLog(const TAchar* pFmt,...);
#endif
//////////////////////////////////////////////////////////////////////////
#if defined(_XTRACE_OUTCONSOLE)
	TVoid xOut(const TChar* pFmt,...);
#endif
//////////////////////////////////////////////////////////////////////////
#if defined(_XTRACE_DBGCONSOLE)
	TVoid xDbg(const TChar* pFmt,...);
#endif
//////////////////////////////////////////////////////////////////////////
#if defined(_XTRACE_MSGBOX)
	TVoid xMessageBox(const TChar* pFmt,...);
#endif
//////////////////////////////////////////////////////////////////////////



	

#if defined(_XTRACE_ASSERT)
#define  xAssertA(exp) if(!(exp)){xTrace0A(eType_OutConsol,E,#exp##"\r\n");(*(TInt*)0) = 0;}
#define  xAssertW(exp) if(!(exp)){xTrace0W(eType_OutConsol,E,##L#exp##"\r\n");(*(TInt*)0) = 0;}
#else
	#define  xAssertA(exp) do{}while(0)
	#define  xAssertW(exp) do{}while(0)
#endif

#if defined(XUNICODE)
	#define  xAssert(exp) xAssertW(exp)
#else
	#define xAssert(exp) xAssertA(exp)
#endif
//////////////////////////////////////////////////////////////////////////
#if defined(_XTRACE_PRINTF)
	#define xPrintf0A(msg)						xTraceA(eType_OutConsol,I,msg)
	#define xPrintf1A(msg,arg1)					xTraceA(eType_OutConsol,I,msg,arg1)
	#define xPrintf2A(msg,arg1,arg2)			xTraceA(eType_OutConsol,I,msg,arg1,arg2)
	#define xPrintf3A(msg,arg1,arg2,arg3)		xTraceA(eType_OutConsol,I,msg,arg1,arg2,arg3)
	#define xPrintf4A(msg,arg1,arg2,arg3,arg4)	xTraceA(eType_OutConsol,I,msg,arg1,arg2,arg3,arg4)

	#define xPrintf0W(msg)						xTraceW(eType_OutConsol,I,msg)
	#define xPrintf1W(msg,arg1)					xTraceW(eType_OutConsol,I,msg,arg1)
	#define xPrintf2W(msg,arg1,arg2)			xTraceW(eType_OutConsol,I,msg,arg1,arg2)
	#define xPrintf3W(msg,arg1,arg2,arg3)		xTraceW(eType_OutConsol,I,msg,arg1,arg2,arg3)
	#define xPrintf4W(msg,arg1,arg2,arg3,arg4)	xTraceW(eType_OutConsol,I,msg,arg1,arg2,arg3,arg4)
#else//_XTRACE_PRINTF
	#define xPrintf0A(msg)						do{}while(0)
	#define xPrintf1A(msg,arg1)					do{}while(0)
	#define xPrintf2A(msg,arg1,arg2)			do{}while(0)
	#define xPrintf3A(msg,arg1,arg2,arg3)		do{}while(0)
	#define xPrintf4A(msg,arg1,arg2,arg3,arg4)	do{}while(0)

	#define xPrintf0W(msg)						do{}while(0)
	#define xPrintf1W(msg,arg1)					do{}while(0)
	#define xPrintf2W(msg,arg1,arg2)			do{}while(0)
	#define xPrintf3W(msg,arg1,arg2,arg3)		do{}while(0)
	#define xPrintf4W(msg,arg1,arg2,arg3,arg4)	do{}while(0)
#endif//_XTRACE_PRINTF

#if  defined(XUNICODE)
	#define xPrintf0							xPrintfW
	#define xPrintf1							xPrintfW
	#define xPrintf2							xPrintfW
	#define xPrintf3							xPrintfW
#else//!XUNICODE
	#define xPrintf0							xPrintfA
	#define xPrintf1							xPrintfA
	#define xPrintf2							xPrintfA
	#define xPrintf3							xPrintfA
#endif//XUNICODE
//////////////////////////////////////////////////////////////////////////
//xInfor
#if defined(_XTRACE_INFO)
	//#define xInfor(...)							xTrace(eType_OutConsol,I,__VA_ARGS__)

	#define xInfor0A(msg)						xTrace0A(eType_OutConsol,I,msg##"")
	#define xInfor1A(msg,arg1)					xTrace1A(eType_OutConsol,I,msg##"",arg1)
	#define xInfor2A(msg,arg1,arg2)				xTrace2A(eType_OutConsol,I,msg##"",arg1,arg2)
	#define xInfor3A(msg,arg1,arg2,arg3)		xTrace3A(eType_OutConsol,I,msg##"",arg1,arg2,arg3)
	#define xInfor4A(msg,arg1,arg2,arg3,arg4)	xTrace4A(eType_OutConsol,I,msg##"",arg1,arg2,arg3,arg4)

	#define xInfor0W(msg)						xTrace0W(eType_OutConsol,I,msg##TEXT(""))
	#define xInfor1W(msg,arg1)					xTrace1W(eType_OutConsol,I,msg##TEXT(""),arg1)
	#define xInfor2W(msg,arg1,arg2)				xTrace2W(eType_OutConsol,I,msg##TEXT(""),arg1,arg2)
	#define xInfor3W(msg,arg1,arg2,arg3)		xTrace3W(eType_OutConsol,I,msg##TEXT(""),arg1,arg2,arg3)
	#define xInfor4W(msg,arg1,arg2,arg3,arg4)	xTrace4W(eType_OutConsol,I,msg##TEXT(""),arg1,arg2,arg3,arg4)
#else//_XTRACE_INFO
	#define xInfor(...)

	#define xInfor0A(msg)						do{}while(0)
	#define xInfor1A(msg,arg1)					do{}while(0)
	#define xInfor2A(msg,arg1,arg2)				do{}while(0)
	#define xInfor3A(msg,arg1,arg2,arg3)		do{}while(0)
	#define xInfor4A(msg,arg1,arg2,arg3,arg4)	do{}while(0)

	#define xInfor0W(msg)						do{}while(0)
	#define xInfor1W(msg,arg1)					do{}while(0)
	#define xInfor2W(msg,arg1,arg2)				do{}while(0)
	#define xInfor3W(msg,arg1,arg2,arg3)		do{}while(0)
	#define xInfor4W(msg,arg1,arg2,arg3,arg4)	do{}while(0)
#endif//_XTRACE_INFO

#if  defined(XUNICODE)
	#define xInfor0								xInfor0W
	#define xInfor1								xInfor1W
	#define xInfor2								xInfor2W
	#define xInfor3								xInfor3W
	#define xInfor4								xInfor4W
#else//!XUNICODE
	#define xInfor0								xInfor0A
	#define xInfor1								xInfor1A
	#define xInfor2								xInfor2A
	#define xInfor3								xInfor3A
	#define xInfor4								xInfor4W
#endif//XUNICODE
//////////////////////////////////////////////////////////////////////////
//xWarning
#if defined(_XTRACE_WARINIG)
//	#define xWarning(...)						xTrace(eType_OutConsol,W,__VA_ARGS__)

	#define xWarning0W(msg)						xTrace0W(eType_OutConsol,W,msg##L(""))
	#define xWarning1W(msg,arg1)				xTrace1W(eType_OutConsol,W,msg##L(""),arg1)
	#define xWarning2W(msg,arg1,arg2)			xTrace2W(eType_OutConsol,W,msg##L(""),arg1,arg2)
	#define xWarning3W(msg,arg1,arg2,arg3)		xTrace3W(eType_OutConsol,W,msg##L(""),arg1,arg2,arg3)

	#define xWarning0A(msg)						xTrace0A(eType_OutConsol,W,msg##(""))
	#define xWarning1A(msg,arg1)				xTrace1A(eType_OutConsol,W,msg##(""),arg1)
	#define xWarning2A(msg,arg1,arg2)			xTrace2A(eType_OutConsol,W,msg##(""),arg1,arg2)
	#define xWarning3A(msg,arg1,arg2,arg3)		xTrace3A(eType_OutConsol,W,msg##(""),arg1,arg2,arg3)
#else//_XTRACE_WARINIG
	#define xWarning(...)

	#define xWarning0A(msg)						do{}while(0)
	#define xWarning1A(msg,arg1)				do{}while(0)
	#define xWarning2A(msg,arg1,arg2)			do{}while(0)
	#define xWarning3A(msg,arg1,arg2,arg3)		do{}while(0)

	#define xWarning0W(msg)						do{}while(0)
	#define xWarning1W(msg,arg1)				do{}while(0)
	#define xWarning2W(msg,arg1,arg2)			do{}while(0)
	#define xWarning3W(msg,arg1,arg2,arg3)		do{}while(0)
#endif//_XTRACE_WARINIG

#if  defined(XUNICODE)
	#define xWarning0							xWarning0W
	#define xWarning1							xWarning1W
	#define xWarning2							xWarning2W
	#define xWarning3							xWarning3W
#else//!XUNICODE
	#define xWarning0							xWarning0A
	#define xWarning1							xWarning1A
	#define xWarning2							xWarning2A
	#define xWarning3							xWarning3A
#endif//XUNICODE

//////////////////////////////////////////////////////////////////////////
//xError
#if defined(_XTRACE_ERROR)
//	#define xError(...)							xTrace(eType_OutConsol,M,__VA_ARGS__)

	#define xError0A(msg)						xTrace0A(eType_OutConsol,E,msg##(""))
	#define xError1A(msg,arg1)					xTrace1A(eType_OutConsol,E,msg##(""),arg1)
	#define xError2A(msg,arg1,arg2)				xTrace2A(eType_OutConsol,E,msg##(""),arg1,arg2)
	#define xError3A(msg,arg1,arg2,arg3)		xTrace3A(eType_OutConsol,E,msg##(""),arg1,arg2,arg3)

	#define xError0W(msg)						xTrace0W(eType_OutConsol,E,msg##TEXT(""))
	#define xError1W(msg,arg1)					xTrace1W(eType_OutConsol,E,msg##TEXT(""),arg1)
	#define xError2W(msg,arg1,arg2)				xTrace2W(eType_OutConsol,E,msg##TEXT(""),arg1,arg2)
	#define xError3W(msg,arg1,arg2,arg3)		xTrace3W(eType_OutConsol,E,msg##TEXT(""),arg1,arg2,arg3)
#else
	#define xError(...)

	#define xError0A(msg)						do{}while(0)
	#define xError1A(msg,arg1)					do{}while(0)
	#define xError2A(msg,arg1,arg2)				do{}while(0)
	#define xError3A(msg,arg1,arg2,arg3)		do{}while(0)

	#define xError0W(msg)						do{}while(0)
	#define xError1W(msg,arg1)					do{}while(0)
	#define xError2W(msg,arg1,arg2)				do{}while(0)
	#define xError3W(msg,arg1,arg2,arg3)		do{}while(0)
#endif
#if  defined(XUNICODE)
	#define xError0								xError0A
	#define xError1								xError1A
	#define xError2								xError2A
	#define xError3								xError3A
#else//!XUNICODE
	#define xError0								xError0W
	#define xError1								xError1W
	#define xError2								xError2W
	#define xError3								xError3W
#endif//XUNICODE
//////////////////////////////////////////////////////////////////////////
}//NLib
#endif // xDebug_H__